import { defineComponent, ref, inject, watchEffect, computed } from 'vue'
import { NSelect } from 'naive-ui'
import type { questionSideListState } from '@/types/baseConfig'
import type { addQueryState } from '@/types/form'
import { keyToSlotName } from '@/utils/dyForm'
import questionOption from '@/basic/addEdit/questionsOption'
import type { PropType, Ref } from 'vue'
import { getSelectFilter } from '@/utils/codeSecure'
import http from '@/basic/baseHttp/index'

export default defineComponent({
  props: {
    compData: {
      type: Object as PropType<questionSideListState>,
      default: () => {
        return {}
      }
    }
  },
  emits: ['change'],
  setup(props: any, { emit }) {
    const queryForm = inject('queryForm') as Ref<any> | undefined
    const pageOptionsInfo = inject('pageOptionsInfo') as Ref<any>
    const dySlots = inject('dySlots') as any
    const info = ref<questionSideListState>(questionOption)
    const getAsyncOptions = async (params: any) => {
      if (info.value.SelectInputForm) {
        if (
          info.value.SelectInputForm.queryForm &&
          info.value.SelectInputForm.queryForm.length > 0
        ) {
          info.value.SelectInputForm.queryForm.forEach((el: addQueryState) => {
            if (el.isItem) {
              if (queryForm && queryForm.value) {
                params[el.key] = queryForm.value[el.value]
              }
            } else {
              params[el.key] = el.value
            }
          })
        }
        const { data } = await http.request(info.value.SelectInputForm.getOptionsConfig, params)
        dyOptions.value = data
      }
    }
    watchEffect(() => {
      info.value = props.compData
      if (props.compData.SelectInputForm) {
        if (
          !props.compData.SelectInputForm.remote &&
          props.compData.SelectInputForm.fromType === 'interface' &&
          props.compData.SelectInputForm.getOptionsConfig.api &&
          props.compData.SelectInputForm.getOptionsConfig.method
        ) {
          getAsyncOptions({})
        }
      }
    })
    const handleSearch = async (query: string) => {
      if (!query.length) {
        dyOptions.value = []
        return
      }
      if (info.value.SelectInputForm) {
        info.value.SelectInputForm.loading = true
        const params: any = {}
        params[info.value.SelectInputForm.query] = query
        await getAsyncOptions(params)

        info.value.SelectInputForm.loading = false
      }
    }
    const params = computed(() => {
      const childerProps: any = {}
      if (props.compData?.SelectInputForm) {
        for (const propsKey in props.compData.SelectInputForm) {
          if (propsKey === 'filter') {
            childerProps['filter'] = (pattern: string, option: object) =>
              getSelectFilter(pattern, option, props.compData.SelectInputForm.filter)
          } else if (
            props.compData.SelectInputForm[propsKey] !== undefined &&
            !['fromTypeKey', 'fromType', 'query'].includes(propsKey)
          ) {
            childerProps[propsKey] = props.compData.SelectInputForm[propsKey]
          }
        }
      }
      if (childerProps.remote) {
        childerProps.onSearch = handleSearch
      }
      return childerProps
    })

    const slotName = computed(() => {
      return keyToSlotName(info.value.commonForm.labelKey)
    })
    const onChange = () => {
      emit('change', info.value)
    }

    const dyOptions = ref<any>([])
    const diySlot = computed(() => {
      const slotInfo: any = {}
      if (dySlots) {
        const dySlotsKeys = Object.keys(dySlots)
        dySlotsKeys.forEach((el: string) => {
          const arr = el.split(':')
          if (arr[0] === slotName.value) {
            const name = arr[1]
            slotInfo[name] = dySlots[el]
          }
        })
      }
      return slotInfo
    })

    const options = computed(() => {
      if (
        info.value.SelectInputForm?.remote ||
        info.value.SelectInputForm?.fromType === 'interface'
      ) {
        return dyOptions.value
      } else if (info.value?.SelectInputForm?.fromTypeKey) {
        return pageOptionsInfo.value[info.value.SelectInputForm.fromTypeKey]
      }
      return []
    })

    return () => (
      <div class="text-input w-full">
        {queryForm ? (
          <NSelect
            {...params.value}
            options={options.value}
            v-model:value={queryForm.value[info.value.commonForm.labelKey]}
            update:value={onChange}
            v-slots={diySlot.value}
          />
        ) : (
          <NSelect
            {...params.value}
            options={options.value}
            v-model:value={info.value.commonForm.defaultValue}
            update:value={onChange}
            v-slots={diySlot.value}
          />
        )}
      </div>
    )
  }
})
